package com.tender.utils;

import org.springframework.core.io.ClassPathResource;
import org.springframework.util.Assert;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.util.Base64;
import java.util.Iterator;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;


public class ImageComplexUtil {

    public static BufferedImage compressImage(InputStream inputFileStream, int targetWidth, int targetHeight, boolean rotate, float quality) {
        try {
            // 读取原始图片
            BufferedImage originalImage = ImageIO.read(inputFileStream);

            // 如果需要旋转图片
            if (rotate) {
                originalImage = rotateImage(originalImage);
            }

            // 根据目标宽高压缩图片
            BufferedImage resizedImage = resizeImage(originalImage, targetWidth, targetHeight);

            System.out.println("图片已成功压缩");

            return resizedImage;
        } catch (IOException e) {
            System.err.println("图片压缩失败: " + e.getMessage());
        }
        return null;
    }

    // 根据目标宽高缩放图片
    private static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
        // 创建目标尺寸的图片
        Image resizedImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH);

        // 将缩放后的图像转换为BufferedImage
        BufferedImage resizedBufferedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = resizedBufferedImage.createGraphics();
        g2d.drawImage(resizedImage, 0, 0, null);
        g2d.dispose();

        return resizedBufferedImage;
    }

    // 如果需要旋转图片
    private static BufferedImage rotateImage(BufferedImage originalImage) {
        int width = originalImage.getWidth();
        int height = originalImage.getHeight();

        // 创建一个足够大的缓冲图像，适合旋转后的图像
        BufferedImage rotatedImage = new BufferedImage(height, width, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = rotatedImage.createGraphics();

        // 设置透明背景
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        // 旋转图像90度，图像中心为旋转中心
        g2d.rotate(Math.toRadians(90), height / 2, height / 2);
        g2d.drawImage(originalImage, (height - width) / 2, (width - height) / 2, null);  // 平移以确保图像正确居中
        g2d.dispose();

        return rotatedImage;

    }


    /**
     * 合并两张图片，默认垂直合并。
     * @param img1 第一个图片
     * @param img2 第二个图片
     * @param isHorizontal 是否水平合并，默认垂直合并
     * @return 合并后的BufferedImage
     */
    public static BufferedImage mergeImages(BufferedImage img1, BufferedImage img2, boolean isHorizontal) {
        if (isHorizontal) {
            return mergeImagesHorizontally(img1, img2);
        } else {
            return mergeImagesVertically(img1, img2);
        }
    }

    // 水平合并两个图片
    private static BufferedImage mergeImagesHorizontally(BufferedImage img1, BufferedImage img2) {
        // 创建一个新的BufferedImage，宽度为两张图片宽度之和，高度为两张图片中较高的高度
        int width = img1.getWidth() + img2.getWidth();
        int height = Math.max(img1.getHeight(), img2.getHeight());

        BufferedImage mergedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics g = mergedImage.getGraphics();

        // 绘制第一个图片
        g.drawImage(img1, 0, 0, null);

        // 绘制第二个图片
        g.drawImage(img2, img1.getWidth(), 0, null);

        g.dispose(); // 释放图形上下文资源

        return mergedImage;
    }

    // 垂直合并两个图片
    private static BufferedImage mergeImagesVertically(BufferedImage img1, BufferedImage img2) {
        // 创建一个新的BufferedImage，宽度为两张图片中较宽的宽度，高度为两张图片高度之和
        int width = Math.max(img1.getWidth(), img2.getWidth());
        int height = img1.getHeight() + img2.getHeight();

        BufferedImage mergedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics g = mergedImage.getGraphics();

        // 绘制第一个图片
        g.drawImage(img1, 0, 0, null);

        // 绘制第二个图片
        g.drawImage(img2, 0, img1.getHeight(), null);

        g.dispose(); // 释放图形上下文资源

        return mergedImage;
    }


    public static String mergeTwoPictures(String pic1, String pic2) throws IOException {
        Assert.hasLength(pic1, "图片1的base64字符串不能为空");
        Assert.hasLength(pic2, "图片2的base64字符串不能为空");
        byte[] pic1ByteArray = Base64.getDecoder().decode(pic1);
        byte[] pic2ByteArray = Base64.getDecoder().decode(pic2);

        ByteArrayInputStream pic1InputStream = new ByteArrayInputStream(pic1ByteArray);
        ByteArrayInputStream pic2InputStream = new ByteArrayInputStream(pic2ByteArray);

        // 压缩图片1
        BufferedImage resizedImage1 = compressImage(pic1InputStream, 1000, 1000, true, 1);
        // 压缩图片2
        BufferedImage resizedImage2 = compressImage(pic2InputStream, 1000, 1000, true, 1);
        // 合并图片1 和 图片2
        BufferedImage bufferedImageAfterMerged = ImageMergerUtil.mergeImages(resizedImage1, resizedImage2, false);

        // 创建一个 ByteArrayOutputStream 用于将图像数据写入
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        // 使用 ImageIO 将 BufferedImage 写入 ByteArrayOutputStream
        ImageIO.write(bufferedImageAfterMerged, "JPEG", byteArrayOutputStream);  // 可以根据需要更改图像格式（如 JPG, PNG, 等）
        // 从 ByteArrayOutputStream 获取字节数组，并创建 ByteArrayInputStream
        // 使用你需要的格式，如 PNG 或 JPEG
        // 对压缩
        BufferedImage resizedMergedImage = compressImage(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), 1000, 1000, false, 1);

        byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(resizedMergedImage, "JPEG", byteArrayOutputStream);
        byte[] byteArray = byteArrayOutputStream.toByteArray();
        return Base64.getEncoder().encodeToString(byteArray);
    }


    public static void main(String[] args) throws IOException {
        File outputFil3 = new File("D:\\小朋友自画像_3.png");
        String picMergedStr = mergeTwoPictures(getPic1(), getPic2());
        byte[] pic1ByteArray = Base64.getDecoder().decode(picMergedStr);

        ByteArrayInputStream pic1InputStream = new ByteArrayInputStream(pic1ByteArray);
        BufferedImage bufferedImage = ImageIO.read(pic1InputStream);
        // 获取图像写入器
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
        ImageWriter writer = writers.next();

        // 设置输出流
        ImageOutputStream ios = ImageIO.createImageOutputStream(outputFil3);
        writer.setOutput(ios);

        // 设置压缩参数
        ImageWriteParam param = writer.getDefaultWriteParam();
        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        param.setCompressionQuality(1); // 设置压缩质量

        // 写入压缩后的图像
        writer.write(null, new IIOImage(bufferedImage, null, null), param);
        ios.close();
        writer.dispose();
    }


    public static String getPic1() throws IOException {
        ClassPathResource resource = new ClassPathResource("pic1.txt");
        InputStream inputStream = resource.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            sb.append(line);
        }

        return sb.toString();
    }

    public static String getPic2() throws IOException {
        ClassPathResource resource = new ClassPathResource("pic2.txt");
        InputStream inputStream = resource.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            sb.append(line);
        }

        return sb.toString();
    }


}
